How does quarto site layout works
📋 Table of Contents
- 🔍 How Quarto Site Layout Works
- 🛠️ Layout Extension Options
- 📋 Real-World Implementation: Related Pages
- 🎯 My Recommendations
Understanding how Quarto’s site layout works is crucial for creating effective documentation websites and implementing custom features like Related Pages navigation.
🔍 How Quarto Site Layout Works
1. Core Layout Architecture
Quarto’s layout system uses a three-panel approach that provides flexibility while maintaining consistency:
┌─────────────────────────────────────────────────────────────┐
│ Navbar (Top) │
├──────────────┬─────────────────────────┬───────────────────┤
│ │ │ │
│ Sidebar │ Main Content │ Right Margin │
│ (Left) │ (Center) │ (Right) │
│ │ │ │
│ - Navigation │ - Article Content │ - Table of Contents│
│ - Sections │ - Headers/Footers │ - Related Pages │
│ - Links │ - Body Text │ - Custom Widgets │
│ │ │ │
└──────────────┴─────────────────────────┴───────────────────┘
Key Components:
- Navbar: Top-level navigation with site branding
- Sidebar: Left navigation panel with site structure
- Main Content: Central area for article/page content
- Right Margin: Secondary content like TOCs and Related Pages
2. Layout Components Structure
The layout is controlled by several configuration layers:
**_quarto.yml Configuration:**
website:
navbar:
# Top navigation bar
sidebar:
# Left navigation panel
page-footer:
# Bottom footer content
format:
html:
grid:
sidebar-width: 300px # Left sidebar width
body-width: 900px # Main content width
margin-width: 280px # Right margin widthHTML Structure:
#quarto-sidebar: Left navigation container#quarto-content: Main content area#quarto-margin-sidebar: Right margin container#quarto-header: Top navigation header
3. Client-Side Rendering Process
Quarto’s layout rendering follows this process:
- HTML Generation: Quarto processes markdown and generates HTML structure
- CSS Application: Themes and custom styles are applied to layout containers
- JavaScript Initialization: Client-side scripts initialize interactive components
- Dynamic Updates: Navigation states, active sections, and custom widgets update based on user interaction
JavaScript Event System:
// Quarto fires these events during layout updates
window.document.addEventListener("quarto-sectionChanged", function(e) {
// Fires when user navigates between sections
});
window.document.addEventListener("DOMContentLoaded", function() {
// Fires when initial layout is ready
});🛠️ Layout Extension Options
Option 1: CSS-Only Styling
For visual adjustments and layout modifications, CSS offers powerful customization capabilities.
Grid Layout Customization:
/* Adjust layout proportions */
.page-columns {
grid-template-columns: 300px 1fr 280px; /* sidebar | content | margin */
}
/* Responsive behavior */
@media (max-width: 800px) {
#quarto-sidebar {
display: none; /* Hide sidebar on mobile */
}
}
/* Custom spacing and colors */
#quarto-sidebar {
background-color: #f8f9fa;
border-right: 1px solid #e9ecef;
}Pros:
- Easy to implement
- No programming knowledge required
- Immediate visual feedback
Cons:
- Limited to styling and simple layout changes
- Cannot add new functionalities or dynamic content
Option 2: Custom JavaScript Enhancement
For advanced features like Related Pages, custom JavaScript provides full control over layout behavior.
Example: Related Pages Implementation
// Custom right sidebar enhancement
document.addEventListener('DOMContentLoaded', function() {
// Create custom navigation in right margin
const rightMargin = document.querySelector('#quarto-margin-sidebar');
// Add Related Pages widget
const relatedPages = createRelatedPagesWidget();
rightMargin.appendChild(relatedPages);
// Integrate with navigation.json
loadNavigationConfig().then(config => {
renderRelatedPages(config);
});
});Pros:
- Full control over behavior and interactions
- Can create dynamic, data-driven content
- Integrates with external APIs and configuration files
Cons:
- Requires JavaScript knowledge
- More complex implementation and debugging
Option 3: Quarto Configuration Extensions
Quarto’s built-in configuration options provide layout control without custom code.
Layout Configuration:
format:
html:
grid:
sidebar-width: 250px
body-width: 800px
margin-width: 300px
include-after-body:
- _includes/custom-layout.html # Custom HTML widgets
css:
- custom-layout.css # Layout-specific stylesSidebar Configuration:
website:
sidebar:
style: "floating" # or "docked"
search: true
collapse-level: 2
contents:
# Navigation structurePros:
- No programming required
- Changes apply globally across the project
- Well-integrated with Quarto’s theming system
Cons:
- Limited to options exposed by Quarto
- Cannot create truly custom functionality
Option 4: Quarto Extension Development
For complex, reusable layout enhancements, Quarto extensions provide the most powerful option.
Extension Structure:
my-layout-extension/
├── _extension.yml # Extension metadata
├── custom-layout.lua # Pandoc filters
├── layout.css # Custom styles
├── layout.js # Custom scripts
└── templates/ # Custom templates
Pros:
- Deep integration with Quarto’s build system
- Reusable across projects
- Can define new layout patterns
Cons:
- Requires understanding of Quarto’s extension API
- More upfront development work
🎯 My Recommendations
Based on real implementation experience, here’s the recommended approach:
Decision Guide:
- Start with Option 3 - Use Quarto’s built-in configuration for basic layout changes
- Move to Option 1 - Add CSS for visual enhancements and responsive behavior
- Implement Option 2 - Use JavaScript for dynamic features like Related Pages
- Consider Option 4 - Develop extensions for reusable complex features
Key Extension Points:
Layout Containers:
// Access main layout containers
const sidebar = document.querySelector('#quarto-sidebar');
const content = document.querySelector('#quarto-content');
const rightMargin = document.querySelector('#quarto-margin-sidebar');Navigation Integration:
// Hook into Quarto's navigation events
window.document.addEventListener("quarto-sectionChanged", function(e) {
updateCustomWidgets();
});
// Access sidebar navigation structure
const sidebarItems = document.querySelectorAll('.sidebar-item-text');
const activeItem = document.querySelector('.sidebar-item-text.active');Configuration Integration:
// Load site configuration data
async function loadSiteConfig() {
const response = await fetch('/navigation.json');
return response.json();
}Responsive Behavior:
/* Mobile-first responsive design */
@media (max-width: 800px) {
#custom-right-nav {
display: none; /* Hide custom widgets on mobile */
}
}
@media (min-width: 1200px) {
.page-columns {
grid-template-columns: 320px 1fr 300px; /* More space on large screens */
}
}Performance Considerations:
- Lazy loading: Only load custom widgets when needed
- Event delegation: Use efficient event handling for navigation
- Caching: Cache configuration data to reduce HTTP requests
- Progressive enhancement: Ensure base functionality works without JavaScript
The beauty of Quarto’s layout system is that it uses standard web technologies while providing powerful extension points for custom functionality. The Related Pages implementation demonstrates how to create sophisticated features that feel native to the Quarto experience.
Would you like me to help you implement a specific layout enhancement or explore advanced customization techniques?